package org.sucri.floxs.utils;

import org.sucri.floxs.model.ColumnLayout;
import org.sucri.floxs.model.Accesor;
import org.sucri.floxs.model.AnnotationFields;
import org.sucri.floxs.Tools;
import org.apache.commons.collections15.MultiMap;
import org.apache.commons.collections15.multimap.MultiHashMap;

import java.lang.reflect.Method;
import java.lang.annotation.Annotation;
import java.util.List;
import java.util.Arrays;
import java.util.ArrayList;

/**
 * Created by IntelliJ IDEA.
 * User: Wen Yu
 * Date: Aug 10, 2007
 * Time: 8:14:12 PM
 * To change this template use File | Settings | File Templates.
 */
public class Annotation_Util
{
  public static List<String> getGroupList(Object obj)
  {
    if (obj.getClass().isAnnotationPresent(ColumnLayout.class))
    {
      String g = obj.getClass().getAnnotation(ColumnLayout.class).groups();
      if (Tools.good(g) && !g.equals(ColumnLayout.NULL))
        return Arrays.asList(g.split(";"));
    }
    return null;
  }
  public static <T extends Annotation> MultiMap<String, Method> getAccesorMethods(List<Method> mm)
  {
    MultiMap<String, Method> methods = new MultiHashMap<String, Method>();
    for (Method m : mm)
    {
      Accesor A = m.getAnnotation(Accesor.class);
      if (A != null) methods.put(A.group(), m);
    }
    return methods;
  }
  public static <T extends Annotation> List<Method> getMethods(Object obj, boolean inherited)
  {
    List<Method> methods = new ArrayList<Method>();
    for (Method m : (inherited ? obj.getClass().getDeclaredMethods() :
                                 obj.getClass().getMethods()))
    {
      methods.add(m);
    }
    return methods;
  }
  public static <T extends Annotation> List<Method> getMethods(
      Object obj, Accesor.Mode mode, boolean inherited)
  {
    List<Method> methods = new ArrayList<Method>();
    for (Method m : (inherited ? obj.getClass().getDeclaredMethods() :
                                 obj.getClass().getMethods()))
    {
      Accesor ac = m.getAnnotation(Accesor.class);
      if (ac != null && (mode == null || mode.equals(ac.mode()))) methods.add(m);
    }
    return methods;
  }
  public static AnnotationFields populate(
      Object obj, AnnotationFields cm, Accesor.Mode mode, boolean inherited)
  {
    if (cm == null) cm = new AnnotationFields();

    cm.setGroups(       getGroupList(obj));
    cm.setMethods(      getMethods(obj, mode, inherited));
    cm.setColumnMethods(getAccesorMethods(cm.getMethods()));

    return cm;
  }
}
